package com.xyy.dfapi.utils;

import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSON;
import com.xyy.dfapi.config.ComentCfg;
import com.xyy.dfapi.pojo.ErpLoginInfo;
import com.xyy.dfapi.pojo.ErpResultDto;
import com.xyy.dfapi.utils.http.RedirectUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Map;

@Component
@Slf4j
public class HttpUtils {

    // 发送 POST 请求的方法
    public ErpResultDto dfPost(String url, String body) {
        ErpResultDto erpResultDto = new ErpResultDto();
        try {
            // 发送请求并获取响应
            erpResultDto = sendRequest(url, body);
            // 检查 token 是否无效或过期
            if (isTokenInvalidOrExpired(erpResultDto)) {
                // 移除无效的 token
                CacheUtils.remove(Constant.TOKEN);
                try {
                    // 重新初始化 token
                    initToken();
                    // 再次发送请求
                    return sendRequest(url, body);
                } catch (Exception e) {
                    log.warn("初始化 token 失败：{}", e.getMessage());
                    throw new RuntimeException("初始化 token 失败");
                }
            }
            return erpResultDto;
        } catch (Exception e) {
            log.warn("当前异常请求地址: {} 接口信息: {} 错误信息:【{}】", url, body, e.getMessage());
            return erpResultDto;
        }
    }

    // 初始化 token 的方法
    @PostConstruct
    private void initToken() {
        try {
            initTokenInternal();
        } catch (Exception e) {
            log.warn("初始化 token 时请求失败：{}", e.getMessage());
            throw new RuntimeException("初始化 token 失败");
        }
    }

    private void initTokenInternal() {
        ComentCfg cfg = CfgUtils.getAppDefaultCfg();
        String erpApiHost = cfg.getErpApiHost();
        ErpLoginInfo loginInfo = new ErpLoginInfo();
        loginInfo.setAppId(cfg.getErpAppId());
        loginInfo.setAppSecret(cfg.getErpAppSecret());
        String body = RedirectUtil.doPostByJson(erpApiHost + cfg.getErpLogin(), JSON.toJSONString(loginInfo));
        ErpResultDto<Map<String, Object>> erpResultDto = JSON.parseObject(body, ErpResultDto.class);
        if (erpResultDto.getStatus() != 200 || erpResultDto == null) {
            log.warn("获取Token失败 error {}", JSON.toJSONString(erpResultDto));
        }
        Map<String, Object> result = erpResultDto.getResult();
        CacheUtils.set(Constant.TOKEN, result.get(Constant.TOKEN).toString());
    }

    private boolean isTokenInvalidOrExpired(ErpResultDto erpResultDto) {
        return erpResultDto.getMessage().contains("token 无效或过期") || erpResultDto.getStatus() != 200;
    }

    private ErpResultDto sendRequest(String url, String body) {
        ErpResultDto erpResultDto = new ErpResultDto();
        try {
            String request = RedirectUtil.doPostByJson(url, MapUtil.of(Constant.TOKEN, CacheUtils.get(Constant.TOKEN).toString()), body, 0);
            erpResultDto = JSON.parseObject(request, ErpResultDto.class);
        } catch (Exception e) {
            log.error("请求异常: {}", e.getMessage());
            return erpResultDto;
        }
        return erpResultDto;
    }
}